package com.myt.matp.gui;

import com.myt.matp.core.Event;

import java.util.Vector;
import java.util.Enumeration;


/**
 * Describe class <code>UIContainer</code> here.
 *
 * @author <a href="mailto:emadridm@gmail.com">Enrique Madrid</a>
 * @version 1.0
 */
public abstract class UIContainer extends UIScroll {

    public static final int FLAG_CIRCULAR = 0x00000001;

    private Vector m_Widgets = new Vector(8);
    private UIWidget m_Focused = null;

    protected UIContainer(int id, GUI gui) {
	super(id, gui);
    }

    public final UIWidget getFocused() {
	return m_Focused;
    }

    private final void setFocused(UIWidget uiw) {
	if ((m_Focused != null) &&
	    !m_Focused.equals(uiw)) {
	    m_Focused.unsetFocus();
	}
	m_Focused = uiw;
	//m_Focused.setFocus();
    }

    public void add(UIWidget uiw) {
	if ((typeContained() == UIWidget.UNKNOW) ||
	    typeContained() == uiw.getType()) {
	    m_Widgets.addElement(uiw);
	}
    }

    public final UIWidget get(int id) {
	Enumeration e;
	UIWidget uiw;
	UIWidget ret = null;

	e = m_Widgets.elements();
	while (e.hasMoreElements()) {
	    uiw = (UIWidget)e.nextElement();
	    if (uiw.getId() == id) {
		ret = uiw;
	    }
	}

	return ret;
    }

    public final int getSize() {
	return m_Widgets.size();
    }

    public final UIWidget elementAt(int index) {
	return (UIWidget)m_Widgets.elementAt(index);
    }

    public final boolean setFocusAt(int index) {
	UIWidget uiw;
	boolean ret = false;

	if ((getSize() > 0) && (index < getSize())) {
	    uiw = (UIWidget)m_Widgets.elementAt(index);
	    if (uiw.setFocus()) {
		setFocused(uiw);
		ret = true;
	    }
	}

	return ret;
    }

    public Enumeration getElements() {
	return m_Widgets.elements();
    }

    public final int indexOf(UIWidget uiw) {
	return m_Widgets.indexOf(uiw);
    }

    public final boolean isContained(UIWidget uiw) {
	return (indexOf(uiw) > -1);
    }

    protected final boolean searchFocus(int route) {
	int size;
	int index;
	boolean ret = false;
	UIWidget uiw = null;

	size = getSize();
	// If not focused
	if (m_Focused == null) {
	    index = (route == -1) ? size : -1;
	}
	else {
	    index = indexOf(m_Focused);
	}

	index += route;
	while ((index >= 0) && (index < size)) {
	    uiw = (UIWidget)elementAt(index);
	    if (uiw.setFocus()) {
		setFocused(uiw);
		ret = true;
		break;
	    }
	    index += route;
	}

	return ret;
    }

    /**
     * Describe <code>findFocus</code> method here.
     *
     * 
     *
     * @param route an <code>int</code> value
     */
    /*
    protected final void findFocus(int route) {
	int size;
	int index;
	UIWidget uiw;

	size = getSize();

	// If not focused
	if (m_Focused == null) {
	    index = (route == -1) ? size : -1;
	}
	else {
	    index = indexOf(m_Focused);
	}


	while (size > 0) {

	    index += route;

	    if ((index < 0) && (route == -1)) {
		if (hasFlags(FLAG_CIRCULAR)) {
		    index = getSize() - 1;
		}
		else {
		    break;
		}
	    }

	    if ((index == getSize()) && (route == 1)) {
		if (hasFlags(FLAG_CIRCULAR)) {
		    index = 0;
		}
		else {
		    break;
		}
	    }

	    uiw = (UIWidget)elementAt(index);

	    if (uiw.setFocus()) {
		setFocused(uiw);
		break;
	    }

	    size--;
	}
    }
    */

    public final boolean dispatchEvent(final Event e) {
	boolean ret = true;

	if (!dispatchEventFocused(e)) {
	    if (!dispatchEventUIContainer(e)) {
		ret = super.dispatchEvent(e);
	    }
	}

	return ret;
    }

    private boolean dispatchEventFocused(final Event e) {
	boolean ret = false;
	if (m_Focused != null) {
	    ret = m_Focused.dispatchEvent(e);
	}
	return ret;
    }

    protected boolean dispatchEventUIContainer(final Event e) {
	boolean ret = true;
	UIWidget uiw;
	
	switch (e.getId()) {
	case Event.UI_TAB:
	    ret = eventUITab(e);
	    break;
	case Event.UI_KEY_RELEASED:
	    ret = eventUIKeyReleased(e);
	default:
	    ret = false;
	    break;
	}

	return ret;
    }

    private boolean eventUITab(final Event e) {
	boolean ret = false;
	if (isContained((UIWidget)e.getObject())) {
	    ret = true;
	    switch (e.getWParam()) {
	    case GUI.KEY_RIGHT:
	    case GUI.KEY_DOWN:
		ret = false;
		if (searchFocus(1)){
		    if (indexOf(getFocused()) == getFrame() + getRedisplay()) {
			resetVerticalFrame();
		    }
		    ret = true;
		    redraw();
		}
		break;
	    case GUI.KEY_LEFT:
	    case GUI.KEY_UP:
		ret = false;
		if (searchFocus(-1)){
		    if (indexOf(getFocused()) == getFrame()) {
			resetVerticalFrame();
		    }
		    ret = true;
		    redraw();
		}
		break;
	    default:
		ret = false;
	    }
	}
	return ret;
    }

    private boolean eventUIKeyReleased(final Event e) {
	boolean ret = false;
	switch (e.getWParam()) {
	case GUI.KEY_DOWN:
	    break;
	case GUI.KEY_UP:
	    break;
	}
	return ret;
    }

    protected final void setRepaint(boolean repaint) {
	UIWidget uiw;
	super.setRepaint(repaint);
	for (int i = 0; i < getSize(); i++) {
	    uiw = elementAt(i);
	    uiw.setRepaint(repaint);
	}
    }

    protected final void paintUIScroll(MGraphics g) {
        //#ifdef DEBUG_UICONTAINER
        //# System.out.println(getClass().getName() + ".paintUIScroll() {");
        //#endif

	if (m_Focused == null) {
	    searchFocus(1);
	}
	// paint container
	paintUIContainer(g);

        //#ifdef DEBUG_UICONTAINER
        //# System.out.println("}");
        //#endif
    }

    protected int computeContent() {
	return getSize();
    }

    protected abstract int typeContained();

    protected abstract void paintUIContainer(MGraphics g);
}
